#include <sdk/util.h>

#include <string>
#include <algorithm>

#include <windows.h>

#pragma comment(lib, "Advapi32.lib")

#	define is_dir(dat) (dat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
#	define is_same(name1, name2) (name1 == name2)
bool find_dir(const char* _path, const char* _dir)
{
	std::string search_path = _path;
	search_path += "\\*";

	std::string obj_dir = _dir;

	WIN32_FIND_DATA find_data;
	HANDLE h_find = ::FindFirstFile(search_path.c_str(), &find_data);
	if(h_find != INVALID_HANDLE_VALUE)
	{
		while( ::FindNextFile(h_find, &find_data) )
		{
			if( !is_dir(find_data)
				|| is_same(find_data.cFileName, ".")
				|| is_same(find_data.cFileName, "..") )
				continue;

			std::string find_low_case = find_data.cFileName;
			std::transform(find_low_case.begin(), find_low_case.end(), find_low_case.begin(), ::tolower);

			if(is_same(find_low_case, obj_dir) )
			{
				::FindClose(h_find);
				return true;
			}
		}
	}

	::FindClose(h_find);
	return false;
}

bool find_file(const char* _path, const char* _file)
{
	std::string search_path = _path;
	search_path += "\\*";

	std::string obj_file = _file;

	WIN32_FIND_DATA find_data;
	HANDLE h_find = ::FindFirstFile(search_path.c_str(), &find_data);
	if(h_find != INVALID_HANDLE_VALUE)
	{
		while( ::FindNextFile(h_find, &find_data) )
		{
			if( is_dir(find_data)
				|| is_same(find_data.cFileName, ".")
				|| is_same(find_data.cFileName, "..") )
				continue;

			std::string find_low_case = find_data.cFileName;
			std::transform(find_low_case.begin(), find_low_case.end(), find_low_case.begin(), ::tolower);

			if(is_same(find_low_case, obj_file) )
			{
				::FindClose(h_find);
				return true;
			}
		}
	}

	::FindClose(h_find);
	return false;
}
#	undef is_dir
#	undef is_same

bool create_dir(const char* _path)
{
	SECURITY_ATTRIBUTES sa;
	SECURITY_DESCRIPTOR sd;

	::InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
	::SetSecurityDescriptorDacl(&sd,TRUE,NULL,FALSE);
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = &sd;

	return ::CreateDirectory(_path, &sa) == TRUE;
}

bool force_move_file(const char* _src_file, const char* _dst_file)
{
	if( FALSE == ::MoveFile(_src_file, _dst_file) )
	{
		return ::DeleteFile(_src_file) == TRUE;
	}
	return true;
}



bool copy_file(const char* _src_file, const char* _dst_file)
{
	return ::CopyFile(_src_file, _dst_file, FALSE) == TRUE;
}